package com.bys.core;

import com.bys.pojo.MappedStatement;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;

/**
 * 负责 执行SQL 语句的 会话对象
 *
 * @author bys
 * @version 1.0
 * @since 1.0
 */
public class SqlSession {
    private SqlSessionFactory sqlSessionFactory;

    public SqlSession() {
    }

    public SqlSession(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }
    public Object selectOne(String sqlId,Object paramsObj) throws SQLException {
        Object obj = null;
        MappedStatement mappedStatement = sqlSessionFactory.getMappedStatements().get(sqlId);
//      原始的sql
        String godMyBatisSql = mappedStatement.getSql();
//        执行的sql
        String sql = godMyBatisSql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");
        Connection connection = sqlSessionFactory.getTransaction().getConnection();
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        Map<Integer, String> paramsMap = getParamsMap(godMyBatisSql);
        paramsMap.forEach((k,v) ->{
            try {
                prepareStatement.setString(k,paramsObj.toString());
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        try {
            ResultSet resultSet = prepareStatement.executeQuery();
            while(resultSet.next()){
                String pojoClassPath = mappedStatement.getResultType();
                Class<?>  pojoClass = Class.forName(pojoClassPath);
                Constructor<?> pojoConstructor = pojoClass.getDeclaredConstructor();
                obj = pojoConstructor.newInstance();
//                给对象属性赋值
                ResultSetMetaData metaData = resultSet.getMetaData();
                int metaCount = metaData.getColumnCount();
                for (int i = 1; i <= metaCount; i++) {
                    String columnName = metaData.getColumnName(i);
                    String setMethodName = "set" + columnName.toUpperCase().charAt(0) + columnName.substring(1);
                    Method setMethod = pojoClass.getDeclaredMethod(setMethodName, pojoClass.getDeclaredField(columnName).getType());
                    setMethod.invoke(obj, resultSet.getString(columnName));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  obj;
    }

    public int insert(String sqlId, Object pojo) {
        int count = 0;
        MappedStatement mappedStatement = sqlSessionFactory.getMappedStatements().get(sqlId);
        String godBatisSql = mappedStatement.getSql();
        String sql = godBatisSql.replaceAll("#\\{[a-zA-Z0-9_$]*}", "?");
        Connection connection = sqlSessionFactory.getTransaction().getConnection();
        try {
            PreparedStatement prepareStatement = connection.prepareStatement(sql);
//            转换sql
           Map<Integer,String> map = getParamsMap(godBatisSql);
           map.forEach((k,v) ->{
               try {
//                   获取实际的值 通过反射获取实际的值，然后放入？当中
                   String getMethodName = "get" + v.toUpperCase().charAt(0) + v.substring(1);
                   Method getMethod = pojo.getClass().getDeclaredMethod(getMethodName);
                   String getProperty = getMethod.invoke(pojo).toString();
                   prepareStatement.setString(k,getProperty);
               } catch (Exception e) {
                   e.printStackTrace();
               }
           });

            count = prepareStatement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return count;
    }
    /**
     * 解析sql 中的参数
     * @param godBatisSql
     * @return Map key 是 位置， value 是属性名
     */
    private Map<Integer, String> getParamsMap(String godBatisSql) {
        Map<Integer,String> map = new HashMap<>();
        int beginIndex = 0;
        int index = 0;
        while (godBatisSql.indexOf("#")  >= 0 ) {
            beginIndex = godBatisSql.indexOf("#");
            int rightKuoHaoIndex = godBatisSql.indexOf("}");
            String property = godBatisSql.substring(beginIndex + 2, rightKuoHaoIndex);
            godBatisSql = godBatisSql.substring(rightKuoHaoIndex + 1);
            index++;
            map.put(index,property);
        }
        return map;

    }


    /**
     * 提交事务
     */
    public void commit() {
        sqlSessionFactory.getTransaction().commit();
    }

    /**
     * 回滚事务
     */
    public void rollback() {
        sqlSessionFactory.getTransaction().rollback();
    }

    /**
     * 关闭连接
     */
    public void close() {
        sqlSessionFactory.getTransaction().close();
    }
}
